home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1997 September
/
Macworld (1997-09).dmg
/
Serious Software
/
Cherwell Scientific Demos
/
pro Fit
/
pro Fit 5.0 demo (fpu).sea
/
pro Fit 5.0 demo (fpu)
/
Functions & Programs
/
•Gadgets
/
Projection 3D
< prev
next >
Wrap
Text File
|
1996-06-01
|
4KB
|
117 lines
{
this program takes a three dimensional data set, defined by its x-, y-, and z- coordinates, and projects
its points onto the plane perpendicular to a vector e in such a way that the position vector of
the first point (i.e. the one in the first non empty row of the x-y-z columns) that is read in is
made vertical.
The two dimensional picture obtained by the projection is then rotated by an angle phi.
The resulting data set is stored in two data columns.
To make things faster, the program assumes that if the xCol contains a valid
number, also yCol and zCol do.
To use this program, choose "Add To Menu" from the Misc menu (or click the Add button).
Then choose the program's name from the Misc menu.
}
program Projection3D;
var e1,e2,e3,phi,xCol,yCol,zCol:extended;
a1,a2,a3,b1,b2,b3,c1,c2,c3:extended;
xx,yy,xxC,yyC,L,phi0, CosPhi, SinPhi:extended;
i:integer;
procedure initialize;
begin
e1:=1;e2:=1;e3:=3;phi:=0;
xCol:=1;yCol:=2;zCol:=3;xxC:=4;yyC:=5;
end;
function sp(x1,x2,x3,y1,y2,y3:extended):extended; {scalar product of two vectors}
begin
sp:=x1*y1+x2*y2+x3*y3
end;
begin
{reset phi. See below}
phi:=(phi-phi0)*180/pi;
{first, ask for input and output columns}
SetBoxTitle('Input and output columns');
for i:=1 to NrCols do
begin
if ColEmpty(i) then leave
end;
xxC:=i;
for i:=xxC+1 to NrCols do
begin
if ColEmpty(i) then leave
end;
yyC:=i;
Input('$Cx Column',xCol,'$Cy Colum',yCol,'$Cz Colum',zCol,'$Coutput x Col',xxC,'$Coutput y-col',yyC);
{then, ask the viewing direction (e) and the rotation angle of the final 2-D output}
SetBoxTitle('projection direction and rotation angle');
Input('e1=',e1,'e2=',e2,'e3=',e3,'rotation angle',phi);
{normalise the vector e}
L:=sqrt(sqr(e1)+sqr(e2)+sqr(e3));
e1:=e1/L;
e2:=e2/L;
e3:=e3/L;
{find a unit vector a perpendicular to e}
if e2=0 then begin a1:=0;a2:=1;a3:=0 end else
begin
a1:=1;a2:=-e1/e2;a3:=0;
a1:=a1/sqrt(1+sqr(a2));
a2:=a2/sqrt(1+sqr(a2));
end;
{calculate the unit vector perpendicular to both e and a: cross product!}
b1:=e2*a3-e3*a2;
b2:=e3*a1-e1*a3;
b3:=e1*a2-e2*a1;
i:=0;
repeat i:=i+1 until dataok(i,xCol); {find the first data row}
{find the length L of the projection of the position vector on e}
L:=sp(data[i,xCol],data[i,yCol],data[i,zCol],e1,e2,e3);
{find c, the component of the position vector perpendicular to e}
c1:=data[i,xCol]-L*e1;c2:=data[i,yCol]-L*e2;c3:=data[i,zCol]-L*e3;
{find the lenghts xx and yy of the components of c along the unit vectors a and b}
xx:=sp(c1, c2,c3,a1,a2,a3);
yy:=sp(c1, c2,c3,b1,b2,b3);
{the first position vector read in is made vertical by default, do not do it if the projection of the position vector gives zero}
if (xx=0) and (yy=0) then phi0:=0 else phi0:=pi/2-arctan(yy/xx);
{rotating th output by phi0 produces verticality of the first position vector which is read in}
{add the user defined angle to this angle}
phi:=pi*phi/180+phi0;
{calculate the elements of the rotation matrix}
CosPhi:=cos(phi);SinPhi:=Sin(phi);
{store the rotated output in the two output columns}
data[i,xxC]:=xx*CosPhi-yy*SinPhi;
data[i,yyC]:=xx*SinPhi+yy*CosPhi;
i:=i+1;{go to the next row }
while (i<=NrRows) do {calculate the projection for each data raw}
begin
if dataok(i,xCol) then
begin
L:=sp(data[i,xCol],data[i,yCol],data[i,zCol],e1,e2,e3);
c1:=data[i,xCol]-L*e1;c2:=data[i,yCol]-L*e2;c3:=data[i,zCol]-L*e3;
xx:=sp(c1, c2,c3,a1,a2,a3);
yy:=sp(c1, c2,c3,b1,b2,b3);
data[i,xxC]:=xx*CosPhi-yy*SinPhi;
data[i,yyC]:=xx*SinPhi+yy*CosPhi;
end;
i:=i+1;
end;
end;